package com.listen.service.impl;

import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.listen.common.DateFormatUtil;
import com.listen.common.HttpClientUtil;
import com.listen.common.SpecialCharacterHandler;
import com.listen.model.User;

import net.sf.json.JSONObject;

/**
 * 八大员听课
 * @author ibm
 *
 */
public class Badayuan{
	private static final Logger log = LoggerFactory.getLogger(Badayuan.class);
	private ConcurrentHashMap<String, String>  resultMap = null;
	private HttpClientUtil httpClient = null;
	private CloseableHttpResponse response = null;
	
	public static void main(String args[]) throws InterruptedException{
		Badayuan instance = new Badayuan();
		String codes = "360731199610117632";//
		instance.start(codes, "劳务员",1,8);
	}
	
	public void start(String codes,String zyName,int start,int end){
		String [] arry = codes.split(",");
		int length = arry.length;
		String zy = getZyByName(zyName);
		for(int i=0;i<length;i++) {
			String code = arry[i];
			for(int num = start;num <= end;num++) {
				User user = new User();
				user.setAllNum(30);
				user.setCode(code);
				user.setPassword("888888");
				user.setZy(zy);
				user.setZyName(zyName);
				user.setNowNum(num);
				listen(user);
				try {
					Thread.sleep(3000L);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	//统一听课
	public Map<String,String> listen(User user){
		httpClient = HttpClientUtil.getInstance();
		resultMap = new ConcurrentHashMap<>();
		resultMap.put("successFlag", "0");
		resultMap.put("dayNum", "0");
		resultMap.put("addNum", "0");
		String code = user.getCode();
		if(code==null||code.trim()==""){
			return null;
		}
		try {
			toLoginPage(user);
		} catch (Exception e) {
			printError(user.getZyName()+"-"+ code +"-听"+user.getNowNum()+"/"+user.getTodayNum()+"节听课异常--->",e);
		}
		return resultMap;
	}
	/**
	 * 解析登录页，获取登录参数
	 * @param 	loginurl 登录地址
	 * @param	prefixUrl 路径前缀(根路径)
	 */
	private void toLoginPage(User user){
		Map<String,String> parmsMap = new ConcurrentHashMap<String,String>();
		String loginUrl = user.getAddress();
		String zy = user.getZy().substring(0,1);
		if(zy.equals("1"))
			user.setIndex("");
		else
			user.setIndex(zy);
		
		if(loginUrl==null){
			switch(zy){
			case "1": loginUrl="http://139.199.204.162:8081/Login.aspx?ZY=1";break;
			case "2": loginUrl="http://139.199.15.78:8081/Login.aspx?ZY=2";break;
			case "3": loginUrl="http://139.199.64.185:8081/Login.aspx?ZY=3";break;
			case "4": loginUrl="http://139.199.65.110:8081/Login.aspx?ZY=4";break;
			case "5": loginUrl="http://139.199.65.98:8081/Login.aspx?ZY=5";break;
			case "6": loginUrl="http://139.199.65.78:8081/Login.aspx?ZY=6";break;
			case "7": loginUrl="http://123.207.89.229:8081/Login.aspx?ZY=7";break;
			case "8": loginUrl="http://139.199.65.78:8082/Login.aspx?ZY=8";break;
			}
		}
		String prefixUrl = loginUrl.substring(0,loginUrl.lastIndexOf("/"));
		try {
			response = httpClient.sendHttpGetResponse(loginUrl);
			int state = response.getStatusLine().getStatusCode();
			if(state == 200){
				HttpEntity entity = response.getEntity();
				String html = EntityUtils.toString(entity);
			    Document document = Jsoup.parse(html);
			    Element parm1 = document.getElementById("__VIEWSTATEGENERATOR");
			    String _viewstategenerator = parm1.attr("value");
			    Element parm2 = document.getElementById("__EVENTVALIDATION");
			    String _eventvalidation = parm2.attr("value");
			    Element parm3 = document.getElementById("__VIEWSTATE");
			    String _viewstate = parm3.attr("value");
			    parmsMap.put("_viewstategenerator", _viewstategenerator);
			    parmsMap.put("_eventvalidation", _eventvalidation);
			    parmsMap.put("_viewstate", _viewstate);
			    parmsMap.put("loginUrl",loginUrl);
			    parmsMap.put("prefixUrl",prefixUrl);
			    this.login(parmsMap,user);
			}else{
				print(user.getZyName()+"-"+ user.getCode() +" -自动获取登录页面参数失败!");
			}
		} catch (Exception e) {
			printError(user.getCode()+"自动获取登录页面参数异常-->",e);
		}finally {
			HttpClientUtil.getInstance().closeResource(response);
		}
	}
	
	//智能听课第三步：智能登录
	public void login(Map<String,String> parmsMap,User user){
		String se = "";
		String zy = user.getZy();
		String loginUrl = parmsMap.get("loginUrl");
		String code = user.getCode();
		String zyName = user.getZyName();
		if(zy.length()==2){
			se = zy.substring(1);
			parmsMap.put("se", se);
		}
		Map<String, String> maps = new ConcurrentHashMap<String, String>();
        maps.put("__VIEWSTATE", parmsMap.get("_viewstate")); 
        maps.put("__VIEWSTATEGENERATOR", parmsMap.get("_viewstategenerator"));
        maps.put("__EVENTVALIDATION",parmsMap.get("_eventvalidation")); 
        maps.put("txtUserName",code);
        maps.put("txtPwd",user.getPassword());
        maps.put("ddlType", "2");
        maps.put("btnLogin", "");
        maps.put("txtLoginName", ""); 
        maps.put("txtDM", "");
        maps.put("txtFR", ""); 
        maps.put("zhjg", "");
        maps.put("zhfr", "");
        if(se !=null && !"".equals(se.trim())){
        	maps.put("se", parmsMap.get("se"));
        }
        try {
        	HttpPost httpPost = new HttpPost(loginUrl);// 创建httpPost
        	httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
        	httpPost.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
        	httpPost.setHeader("DNT", "1");
        	httpPost.setHeader("Upgrade-Insecure-Requests", "1");
        	response = httpClient.sendHttpPost(maps,httpPost);
        	int state = response.getStatusLine().getStatusCode();
        	if(state == 200){
        		int i=0,j=1,k=2;
        		Header[] hearders = response.getHeaders("Set-Cookie");
        		if(hearders.length==4){
        			i=0;j=2;k=3;
        		}
        		String loginCookie = hearders[i].getValue();
        		String sessionId = loginCookie.substring(0, loginCookie.indexOf(";") + 1);
        		String userIdCookie = hearders[j].getValue();
        		String userid = userIdCookie.substring(0, userIdCookie.indexOf(";") + 1);
        		String infoCookies = hearders[k].getValue();
        		String info = infoCookies.substring(0, infoCookies.indexOf(";") + 1);
        		//设置登录信息
        		parmsMap.put("sessionId", sessionId);
        		parmsMap.put("userid", userid);
        		parmsMap.put("info", info);
        		//听课
        		openVideo(parmsMap,user);
        	}else{
        		print("登录失败！！！当前账户-"+code+"-所选职业为:"+zyName+",请检查职业是否匹配!");
        	}
		} catch (Exception e) {
			printError("登录异常,当前账户-"+code+"-所选职业为:"+zyName+"异常信息如下：",e);
		}finally {
			HttpClientUtil.getInstance().closeResource(response);
		}
	}
	
	//打开视频播放界面
	public void  openVideo(Map<String,String> parmsMap,User user){
		String index = user.getIndex();
		String sessionId = parmsMap.get("sessionId");
		String userid = parmsMap.get("userid");
		String prefixUrl = parmsMap.get("prefixUrl");
		String info = parmsMap.get("info");
		String code = user.getCode();
		int i = user.getNowNum();
		String id = i <10 ? "0000" + i : "000" + i;
		String vcodeJson = "{Vcode:\"" + id + "\"}";
		String openUrl = prefixUrl + "/StudentClass"+ index +"/shipinSection"+ index +".aspx/CheckCanWatch?dt="+ SpecialCharacterHandler.replaceBlankSpace(DateFormatUtil.getDateEN(new Date()));
		String cookies = sessionId + userid + info +" RID="+id +"; id="+id;
		//System.out.println(vcodeJson);
		//System.out.println(openUrl);
		//System.out.println(cookies);
		try {
			HttpPost httpPost = new HttpPost(openUrl);// 创建httpPost
			httpPost.setHeader("Accept","application/json, text/javascript");
			httpPost.setHeader("Accept-Encoding","gzip, deflate");
			httpPost.setHeader("Accept-Language","zh-CN,zh;q=0.9");
			httpPost.setHeader("Cookie", cookies);
			httpPost.setHeader("Content-Type","application/json; charset=UTF-8");
			httpPost.setHeader("X-Requested-With","XMLHttpRequest");
			response = httpClient.sendHttpPost(httpPost, vcodeJson);
			int state = response.getStatusLine().getStatusCode();
			String entityStr = EntityUtils.toString(response.getEntity(), "UTF-8");
			//System.out.println(entityStr);
			if(state == 200){
				String msg = (String) JSONObject.fromObject(entityStr).get("d");
				if("".equals(msg)){
					updateStudyVideo(parmsMap,user);
				}else{
					resultMap.put("successFlag", "1");
					resultMap.put("dayNum", "1");
					print(user.getZyName() + "-"+code +"-第"+ i +"打开视频播放界面异常："+msg);
				}
			}else{
				print(user.getZyName() + "-"+code +"-第"+ i +"打开视频播放界面失败，状态："+state);
			}
		} catch (Exception e) {
			printError("打开视频播放界面异常,当前账户-"+code+"-所选职业为:"+user.getZyName()+"异常信息如下：",e);
		}finally {
			HttpClientUtil.getInstance().closeResource(response);
		}
	}
	
	//智能听课第五步：更新课件状态为已听
	public void updateStudyVideo(Map<String,String> parmsMap,User user){
		String code = user.getCode();
		int i = user.getNowNum();
		try {
			HttpPost httpPost = this.getCookieAndUrl(parmsMap, user);
			response = httpClient.sendHttpPost(httpPost, user.getRvCodeJson());
			int state = response.getStatusLine().getStatusCode();
			String entityStr = EntityUtils.toString(response.getEntity(), "UTF-8");
			if(state == 200){
				String msg = (String) JSONObject.fromObject(entityStr).get("d");
				print(user.getZyName() + "-"+code +"-第"+ i +"个视频"+msg);
				resultMap.put("successFlag", "1");
				if("进度更新完毕，请看下个视频".equals(msg)){
					resultMap.put("dayNum", "1");
					resultMap.put("addNum", "1");
				}else if("本视频播放完毕".equals(msg)){
					resultMap.put("addNum", "1");
				}else if("课程全部看完，可以进行考试".equals(msg)){//听完最后一个修改状态为已完成
					user.setStatus(3);
				}else{
					System.out.println("视频播放异常");
				}
			}else{
				print(user.getZyName() + "-"+code +"-第"+ i +"视频播放失败!"+entityStr);
			}
		} catch (Exception e) {
			printError(user.getZyName() +"-"+ code +"-第" +i +" 视频听课异常--->",e);
		}finally {
			HttpClientUtil.getInstance().closeResource(response);
		}
		logout(parmsMap,user);
	}
	
	public void logout(Map<String,String> parmsMap,User user){
		HttpGet httpGet = null;
		String prefixUrl = parmsMap.get("prefixUrl");
		String zy = user.getZy();
		String zyName = user.getZyName();
		String code = user.getCode();
		String sessionId = parmsMap.get("sessionId");
		String userid = parmsMap.get("userid");
		String info = parmsMap.get("info");
		try {
			String path = prefixUrl+"/Public/Logout.aspx?id="+zy;
			httpGet = new HttpGet(path);
			String cookie = sessionId + userid + info +" totaltime=2281; checkUid="+userid+"; nowtime=2281";
			httpGet.setHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
			httpGet.setHeader("Cookie", cookie);
			response = httpClient.sendHttpGet(httpGet);
			int state = response.getStatusLine().getStatusCode();
			if(state == 200 || state == 302){
				//log.info(zyName+"-"+code+"-退出登录成功!");
			}else{
				log.info(zyName+"-"+code+"-退出登录失败!");
			}
		} catch (Exception e) {
			printError(zyName+code+"退出登录错误--->",e);
		}finally{
			httpClient.closeResource(response);
		}
	}
	
	private void print(String msg){
		resultMap.put("msg", msg);
		log.info(msg);
	}
	
	public int getRvCodeJson(int i){
		if(i < 10 || i==18 || i==19 || i==28 || i==29)
			return i;
		else if (i >= 10 && i <= 17)
			return i-2;
		else if(i==30)
			return i - 6;
		else if(i >= 20 || i <= 27)
			return i-4;
		else
			return i;
	}
	
	//构建请求路径、参数、cookie
	public HttpPost getCookieAndUrl(Map<String,String> parmsMap,User user){
		HttpPost httpPost = null;
		String zy = user.getZy().substring(0, 1);
		String index = user.getIndex();
		String sessionId = parmsMap.get("sessionId");
		String userid = parmsMap.get("userid");
		String prefixUrl = parmsMap.get("prefixUrl");
		String host = prefixUrl.substring(prefixUrl.indexOf(":")+3);
		String info = parmsMap.get("info");
		//构造cookie中的 st
		String date = DateFormatUtil.getDateStr(new Date());
		String st = SpecialCharacterHandler.replaceAll(date);
		int i = user.getNowNum();
		String cookie = "";
		String updateUrl = "";
		String rvCodeJson = "";
		String referer = "";
		if("5".equals(zy)){
			//构造cookie中的 rvCode
			String rvCode = i < 10 ? "0000" + i : "000" + i;
			//构造cookie中的 url
			referer =  prefixUrl + "/StudentClass"+ index +"/WatchVideo"+ index +".aspx?ids="+rvCode;
			String url = SpecialCharacterHandler.replaceAll(referer);
			//组装整个cookie
			cookie = sessionId +" "+ userid +" "+ info +" RID=" + rvCode + "; id="+ rvCode + "; safedog-flow-item=; totaltime=2281; url=" + url +"; checkUid="+ userid.split("=")[1] 
						+ " st="+ st +"; PC1=%u6210%u529F; PC2=%u6210%u529F; PC3=%u6210%u529F; PC4=%u6210%u529F; nowtime=2281";
			//构造请求参数
			rvCodeJson = "{RVCode:\"" + rvCode + "\"}";
			updateUrl = prefixUrl + "/StudentClass" + index + "/WatchVideo" + index + ".aspx/UpdateStudyType?dt=" + SpecialCharacterHandler.replaceBlankSpace(DateFormatUtil.getDateEN(new Date()));
			httpPost = new HttpPost(updateUrl);// 创建httpPost
			httpPost.setHeader("Accept","application/json, text/javascript, */*; q=0.01");
			httpPost.setHeader("Accept-Encoding","gzip, deflate");
			httpPost.setHeader("Accept-Language","zh-CN,zh;q=0.9");
			httpPost.setHeader("Cookie", cookie);
			httpPost.setHeader("Host", host);
			httpPost.setHeader("Origin", prefixUrl);
			httpPost.setHeader("Referer",referer);
			httpPost.setHeader("Content-Type","application/json; charset=UTF-8");
			httpPost.setHeader("X-Requested-With","XMLHttpRequest");
		}else{
			//构造cookie中的 rvCode
			String rvCode = i < 10 ? "0000" + i : "000" + i;
			//构造cookie中的 url
			referer =  prefixUrl + "/StudentClass"+ index +"/WatchVideo"+ index +".aspx?ids="+rvCode;
			String url = SpecialCharacterHandler.replaceAll(referer);
			//组装整个cookie
			cookie = sessionId + userid + info + "checkUid=" + userid.split("=")[1] +"RID=" + rvCode + ";id="+ rvCode +";totaltime=2281;url=" + url
						+ ";st="+ st +";nowtime=2281";
			//构造请求参数
			int num = getRvCodeJson(i);
			rvCodeJson = "{RVCode:\"" + num + "\"}";
			updateUrl = prefixUrl + "/StudentClass" + index + "/WatchVideo" + index + ".aspx/UpdateStudyType?dt=" + SpecialCharacterHandler.replaceBlankSpace(DateFormatUtil.getDateEN(new Date()));
			httpPost = new HttpPost(updateUrl);// 创建httpPost
			httpPost.setHeader("Accept","application/json, text/javascript, */*; q=0.01");
			httpPost.setHeader("Accept-Encoding","gzip, deflate");
			httpPost.setHeader("Accept-Language","zh-CN,zh;q=0.9");
			httpPost.setHeader("Cookie", cookie);
			httpPost.setHeader("Host", host);
			httpPost.setHeader("Origin", prefixUrl);
			httpPost.setHeader("Referer",referer);
			httpPost.setHeader("Content-Type","application/json; charset=UTF-8");
			httpPost.setHeader("X-Requested-With","XMLHttpRequest");
		}
		user.setRvCodeJson(rvCodeJson);
		return httpPost;
	}
	
	private void printError(String msg,Exception e){
		msg = msg + e.getMessage();
		resultMap.put("errorMsg", msg);
		log.info(msg,e);
	}
	
	public String getZyByName(String name) {
		switch(name) {
		case "土建施工员":
			return "10";
		case "装饰装修施工员":
			return "11";
		case "设备安装施工员":
			return "12";
		case "市政工程施工员":
			return "13";
		case "标准员" :
			return "2";
		case "材料员" :
			return "3";
		case "机械员" :
			return "4";
		case "安全员" :
			return "5";
		case "资料员" :
			return "6";
		case "土建质量员" :
			return "70";
		case "装饰装修质量员" :
			return "71";
		case "设备安装质量员" :
			return "72";
		case "市政工程质量员" :
			return "73";
		case "劳务员" :
			return "8";
		default :
			return "8";
		}
	}
}
